#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <time.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define ARGS_CHECK(argc, num)               \
    {                                       \
        if (argc != num)                    \
        {                                   \
            fprintf(stderr, args error !n); \
            return -1;                      \
        }                                   \
    }
#define ERROR_CHECK(ret, num, msg) \
    {                              \
        if (ret == num)            \
        {                          \
            perror(msg);           \
            exit(1);               \
        }                          \
    }
int main(int argc, char *argv[])
{
    int fd_s = socket(PF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(-1, fd_s, "socket");
    struct sockaddr_in s_addr, c_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(5000);           // htons把端口号转网路字节序
    s_addr.sin_addr.s_addr = inet_addr("0"); // “0系统根据当前ip自动填充
    // 将IP port socket返回的文件描述符绑定在一起；
    int ret = bind(fd_s, (struct sockaddr *)&s_addr, sizeof(s_addr));
    ERROR_CHECK(-1, ret, "bind");
    // 设置监听队列
    ret = listen(fd_s, 40);
    ERROR_CHECK(-1, ret, "listen");
    //
    puts("listen ..");
    socklen_t len = sizeof c_addr;
    // 循环等待客户端发起的连接请求；
    char buf[128];
    while (1)
    {
        // accept 会阻塞等待客户端的连接
        int newfd = accept(fd_s, (void *)&c_addr, &len);
        if (-1 == newfd)
        {
            perror("accept");
            continue;
        }
        // 当程序执行到此：已有客户端成功建立连接
        // newfd代表对应的连接，所有可以打印连接信息
        // 并处理对应连接的请求；
        printf("client IP:%s,Port:%d connected!\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
        // 接收客户端消息；
        int size;
        int len = sizeof size;
        if (-1 == getsockopt(newfd,SOL_SOCKET,SO_SNDBUF,&size,&len))
        {
            /* code */
        }
        printf("%d\n",size);
        while (1)
        {
            read(newfd, buf, 128);
            printf("recv:%s\n", buf);
            if (0 == strncasecmp(buf, "time", 4))
            {
                /* code */
                time_t tm;
                tm = time(NULL);
                sprintf(buf, "%s", ctime(&tm));
            }
            else if (0 == strncasecmp(buf, "quit", 4))
            {
                break;
            }
            else
            {
                sprintf(buf, "time !!!!\n");
            }
            write(newfd, buf, 128);
        }
        close(newfd);
    }

    return 0;
}
